const express = require('express');
const multer = require('multer');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
const { ExceptionHandler } = require('../consistency');
const { PerformanceMonitor } = require('../performance');

class MediaService {
    constructor() {
        this.app = express();
        this.port = process.env.MEDIA_SERVICE_PORT || 3003;
        this.exceptionHandler = new ExceptionHandler();
        this.performanceMonitor = new PerformanceMonitor();
        
        // 媒体存储
        this.mediaStorage = [];
        this.uploadQueue = [];
        this.activeUploads = 0;
        this.MAX_CONCURRENT_UPLOADS = 3;
        
        this.setupMiddleware();
        this.setupFileUpload();
        this.setupRoutes();
    }

    setupMiddleware() {
        this.app.use(express.json({ limit: '10mb' }));
        this.app.use(express.urlencoded({ extended: true }));
        
        // 性能监控
        this.app.use((req, res, next) => {
            const startTime = Date.now();
            res.on('finish', () => {
                const responseTime = Date.now() - startTime;
                this.performanceMonitor.recordRequest(req.path, req.method, responseTime, res.statusCode);
            });
            next();
        });
    }

    setupFileUpload() {
        // 文件存储配置
        const storage = multer.diskStorage({
            destination: (req, file, cb) => {
                const uploadDir = path.join(__dirname, '../../uploads');
                require('fs').mkdirSync(uploadDir, { recursive: true });
                cb(null, uploadDir);
            },
            filename: (req, file, cb) => {
                const safeName = file.originalname.replace(/[^a-zA-Z0-9.\-]/g, '_');
                const uniqueName = `${uuidv4()}-${safeName}`;
                cb(null, uniqueName);
            }
        });

        this.upload = multer({
            storage: storage,
            limits: {
                fileSize: 10 * 1024 * 1024, // 10MB限制
                files: 5 // 每次最多5个文件
            },
            fileFilter: (req, file, cb) => {
                const allowedTypes = [
                    'image/jpeg', 'image/png', 'image/gif', 'image/webp',
                    'application/pdf', 'text/plain', 'application/msword',
                    'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
                ];
                
                if (allowedTypes.includes(file.mimetype)) {
                    cb(null, true);
                } else {
                    cb(new Error('不支持的文件类型'));
                }
            }
        });
    }

    setupRoutes() {
        // 健康检查
        this.app.get('/health', (req, res) => {
            res.json({
                service: 'media-service',
                status: 'healthy',
                mediaCount: this.mediaStorage.length,
                storageUsage: this.calculateStorageUsage(),
                timestamp: Date.now()
            });
        });

        // 文件上传
        this.app.post('/api/upload', this.upload.array('files', 5), this.handleUpload.bind(this));
        
        // 获取媒体列表
        this.app.get('/api/media', this.getMediaList.bind(this));
        
        // 获取单个媒体信息
        this.app.get('/api/media/:id', this.getMediaInfo.bind(this));
        
        // 删除媒体文件
        this.app.delete('/api/media/:id', this.deleteMedia.bind(this));
        
        // 媒体文件预览
        this.app.get('/api/media/:id/preview', this.previewMedia.bind(this));
        
        // 批量操作
        this.app.post('/api/media/batch', this.batchOperations.bind(this));
        
        // 静态文件服务
        this.app.use('/media', express.static(path.join(__dirname, '../../uploads')));
    }

    // 处理文件上传
    async handleUpload(req, res) {
        try {
            if (!req.files || req.files.length === 0) {
                return res.status(400).json({
                    success: false,
                    message: '没有选择文件'
                });
            }

            const uploadResults = [];
            
            for (const file of req.files) {
                try {
                    const mediaInfo = await this.processFileUpload(file, req.body);
                    uploadResults.push({
                        success: true,
                        file: mediaInfo
                    });
                } catch (error) {
                    uploadResults.push({
                        success: false,
                        filename: file.originalname,
                        error: error.message
                    });
                }
            }

            const successfulUploads = uploadResults.filter(result => result.success);
            const failedUploads = uploadResults.filter(result => !result.success);

            res.json({
                success: true,
                message: `上传完成，成功 ${successfulUploads.length} 个，失败 ${failedUploads.length} 个`,
                data: {
                    successful: successfulUploads,
                    failed: failedUploads
                }
            });

        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/upload' });
            res.status(500).json({
                success: false,
                message: '文件上传失败'
            });
        }
    }

    // 处理单个文件上传
    async processFileUpload(file, metadata = {}) {
        return new Promise((resolve, reject) => {
            const mediaId = uuidv4();
            const fileInfo = {
                id: mediaId,
                filename: file.filename,
                originalName: file.originalname,
                mimetype: file.mimetype,
                size: file.size,
                path: file.path,
                url: `/media/${file.filename}`,
                uploadDate: new Date().toISOString(),
                metadata: {
                    title: metadata.title || file.originalname,
                    description: metadata.description || '',
                    tags: metadata.tags ? metadata.tags.split(',') : []
                },
                dimensions: this.getFileDimensions(file),
                checksum: this.generateFileChecksum(file.path)
            };

            // 保存媒体信息
            this.mediaStorage.push(fileInfo);
            
            // 生成缩略图（如果是图片）
            if (file.mimetype.startsWith('image/')) {
                this.generateThumbnail(file.path, mediaId);
            }

            resolve(fileInfo);
        });
    }

    // 获取文件尺寸（图片）
    getFileDimensions(file) {
        if (file.mimetype.startsWith('image/')) {
            // 实际项目中可以使用sharp库获取图片尺寸
            return { width: 0, height: 0 };
        }
        return null;
    }

    // 生成文件校验和
    generateFileChecksum(filePath) {
        // 实际项目中可以使用crypto生成文件MD5或SHA256
        return 'checksum_' + Date.now();
    }

    // 生成缩略图
    generateThumbnail(filePath, mediaId) {
        // 实际项目中可以使用sharp库生成缩略图
        console.log(`生成缩略图: ${mediaId}`);
    }

    // 获取媒体列表
    getMediaList(req, res) {
        try {
            const { 
                type, 
                page = 1, 
                limit = 20,
                sortBy = 'uploadDate',
                sortOrder = 'desc'
            } = req.query;
            
            let filteredMedia = [...this.mediaStorage];
            
            // 类型过滤
            if (type) {
                filteredMedia = filteredMedia.filter(media => {
                    if (type === 'image') return media.mimetype.startsWith('image/');
                    if (type === 'document') return media.mimetype.startsWith('application/');
                    return media.mimetype.includes(type);
                });
            }
            
            // 排序
            filteredMedia.sort((a, b) => {
                const aValue = a[sortBy];
                const bValue = b[sortBy];
                return sortOrder === 'desc' ? bValue - aValue : aValue - bValue;
            });
            
            // 分页
            const pageNum = parseInt(page);
            const limitNum = parseInt(limit);
            const startIndex = (pageNum - 1) * limitNum;
            const endIndex = startIndex + limitNum;
            const paginatedMedia = filteredMedia.slice(startIndex, endIndex);
            
            res.json({
                success: true,
                data: paginatedMedia,
                pagination: {
                    page: pageNum,
                    limit: limitNum,
                    total: filteredMedia.length,
                    totalPages: Math.ceil(filteredMedia.length / limitNum)
                }
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/media' });
            res.status(500).json({
                success: false,
                message: '获取媒体列表失败'
            });
        }
    }

    // 获取媒体信息
    getMediaInfo(req, res) {
        try {
            const mediaId = req.params.id;
            const mediaInfo = this.mediaStorage.find(media => media.id === mediaId);
            
            if (!mediaInfo) {
                return res.status(404).json({
                    success: false,
                    message: '媒体文件不存在'
                });
            }
            
            res.json({
                success: true,
                data: mediaInfo
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/media/:id' });
            res.status(500).json({
                success: false,
                message: '获取媒体信息失败'
            });
        }
    }

    // 删除媒体文件
    deleteMedia(req, res) {
        try {
            const mediaId = req.params.id;
            const mediaIndex = this.mediaStorage.findIndex(media => media.id === mediaId);
            
            if (mediaIndex === -1) {
                return res.status(404).json({
                    success: false,
                    message: '媒体文件不存在'
                });
            }
            
            const mediaInfo = this.mediaStorage[mediaIndex];
            
            // 删除物理文件
            const fs = require('fs');
            if (fs.existsSync(mediaInfo.path)) {
                fs.unlinkSync(mediaInfo.path);
            }
            
            // 删除记录
            this.mediaStorage.splice(mediaIndex, 1);
            
            res.json({
                success: true,
                message: '媒体文件删除成功',
                data: { id: mediaId }
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/media/:id' });
            res.status(500).json({
                success: false,
                message: '删除媒体文件失败'
            });
        }
    }

    // 媒体预览
    previewMedia(req, res) {
        try {
            const mediaId = req.params.id;
            const mediaInfo = this.mediaStorage.find(media => media.id === mediaId);
            
            if (!mediaInfo) {
                return res.status(404).json({
                    success: false,
                    message: '媒体文件不存在'
                });
            }
            
            // 根据文件类型返回不同的预览信息
            if (mediaInfo.mimetype.startsWith('image/')) {
                res.json({
                    success: true,
                    data: {
                        type: 'image',
                        url: mediaInfo.url,
                        dimensions: mediaInfo.dimensions
                    }
                });
            } else if (mediaInfo.mimetype.startsWith('application/pdf')) {
                res.json({
                    success: true,
                    data: {
                        type: 'pdf',
                        url: mediaInfo.url,
                        pageCount: 1 // 实际项目中可以解析PDF页数
                    }
                });
            } else {
                res.json({
                    success: true,
                    data: {
                        type: 'file',
                        url: mediaInfo.url,
                        mimetype: mediaInfo.mimetype
                    }
                });
            }
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/media/:id/preview' });
            res.status(500).json({
                success: false,
                message: '获取媒体预览失败'
            });
        }
    }

    // 批量操作
    batchOperations(req, res) {
        try {
            const { operations } = req.body;
            
            if (!Array.isArray(operations)) {
                return res.status(400).json({
                    success: false,
                    message: '操作列表格式不正确'
                });
            }
            
            const results = [];
            
            operations.forEach(operation => {
                try {
                    switch (operation.type) {
                        case 'delete':
                            const index = this.mediaStorage.findIndex(media => media.id === operation.mediaId);
                            if (index !== -1) {
                                const mediaInfo = this.mediaStorage[index];
                                
                                // 删除物理文件
                                const fs = require('fs');
                                if (fs.existsSync(mediaInfo.path)) {
                                    fs.unlinkSync(mediaInfo.path);
                                }
                                
                                this.mediaStorage.splice(index, 1);
                                results.push({ 
                                    type: 'delete', 
                                    mediaId: operation.mediaId, 
                                    success: true 
                                });
                            }
                            break;
                        case 'update':
                            const mediaIndex = this.mediaStorage.findIndex(media => media.id === operation.mediaId);
                            if (mediaIndex !== -1) {
                                if (operation.metadata) {
                                    this.mediaStorage[mediaIndex].metadata = {
                                        ...this.mediaStorage[mediaIndex].metadata,
                                        ...operation.metadata
                                    };
                                }
                                results.push({ 
                                    type: 'update', 
                                    mediaId: operation.mediaId, 
                                    success: true 
                                });
                            }
                            break;
                    }
                } catch (error) {
                    results.push({ 
                        type: operation.type, 
                        mediaId: operation.mediaId, 
                        success: false, 
                        error: error.message 
                    });
                }
            });
            
            res.json({
                success: true,
                data: results
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/media/batch' });
            res.status(500).json({
                success: false,
                message: '批量操作失败'
            });
        }
    }

    // 计算存储使用情况
    calculateStorageUsage() {
        const totalSize = this.mediaStorage.reduce((sum, media) => sum + media.size, 0);
        return {
            totalFiles: this.mediaStorage.length,
            totalSize: totalSize,
            totalSizeMB: (totalSize / 1024 / 1024).toFixed(2)
        };
    }

    // 启动服务
    start() {
        return this.app.listen(this.port, () => {
            console.log(`📁 Media Service running on port ${this.port}`);
            console.log(`📊 Health check: http://localhost:${this.port}/health`);
            console.log(`💾 Storage directory: ${path.join(__dirname, '../../uploads')}`);
        });
    }
}

// 如果直接运行此文件，启动服务
if (require.main === module) {
    const mediaService = new MediaService();
    mediaService.start();
}

module.exports = MediaService;